package tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.junit.Before;
import org.junit.Test;

import coreSimulation.Passenger;
import coreSimulation.Queue;
import exceptions.DuplicatePassengerException;

public class QueueTest {

	Queue q;

	/*
	 * Instantiate a Queue object
	 */
	@Before
	public void setUp() {
		q = new Queue();
	}

	/*
	 * Check for the boolean true value returned from the add method of the
	 * Queue class then count the number of items in the queue
	 */
	@Test
	public void testAdd() {
		// ensure the queue is empty
		q.clear();

		Passenger p = new Passenger("Bob Dobbs", "SA-12345678");
		// add passenger and check for true return
		try {
			assertTrue(q.add(p));
		} catch (DuplicatePassengerException e) {
			e.printStackTrace();
			// if it gets here, something went wrong
			fail();
		}
		// count the number of items in the queue and check = 1
		assertEquals(q.size(), 1, 0);
	}

	/*
	 * Test for IllegalArgumentException thrown by the Queue class when a null
	 * Passenger object is passed to the add method
	 */
	@Test(expected = IllegalArgumentException.class)
	public void testAddNull() {
		Passenger p = null;
		try {
			q.add(p); // this should blow up and raise an
						// IllegalArgumentException
		} catch (DuplicatePassengerException e) {
			e.printStackTrace();
			// if it gets here, something went wrong
			fail();
		}
	}

	/*
	 * Test for DuplicatePassengerException thrown by the Queue class when a
	 * passenger with the same booking no as an existing passenger is passed to
	 * the add method
	 */
	@Test(expected = exceptions.DuplicatePassengerException.class)
	public void testAddDuplicate() throws DuplicatePassengerException {
		// Two passengers with the same booking ref
		Passenger p1 = new Passenger("Erica Eller", "SA-55705175");
		Passenger p2 = new Passenger("Dennis Dillow", "SA-55705175");
		// add first passenger
		q.add(p1);

		q.add(p2); // should blow up at this point as passenger p2 has same
					// booking ref as passenger p1

	}

	/*
	 * Test that the integer value returned from the addBulk method of the queue
	 * class is greater than 0
	 */
	@Test
	public void testAddBulk() {
		assertTrue(q.addBulk("PassengerList.csv") > 0);
	}

	
	@Test
	public void testContains() {
		// Two passengers with the same booking ref
		Passenger p1 = new Passenger("Erica Eller", "SA-55705175");
		Passenger p2 = new Passenger("Dennis Dillow", "SA-55705175");
		// add first passenger
		try {
			q.add(p1);
		} catch (DuplicatePassengerException e) {
			e.printStackTrace();
			// if it gets here, something went wrong
			fail();
		}

		// check that the queue contains the second passenger the equals method
		// of the passenger method should determine that they are equal
		// therefore the compare method should determine that p2 is already in
		// the list
		assertTrue(q.contains(p2));

	}

	@Test
	public void testIsEmplty() {
		// empty the queue
		q.clear();
		assertTrue(q.isEmpty());
		// check that it is reported as empty
		Passenger p = new Passenger("Erica Eller", "SA-55705175");

		// add something to the queue
		try {
			q.add(p);
		} catch (DuplicatePassengerException e) {
			e.printStackTrace();
			// if it gets here, something went wrong
			fail();
		}

		// check that the queue doesn't report as empty
		assertFalse(q.isEmpty());

	}

	/**
	 * This test checks not only the index method but also the remove method and
	 * the equals method
	 */
	@Test
	public void testIndexNRemove() {
		q.clear();
		Passenger p1 = new Passenger("Erica Eller", "SA-55705175");
		try {
			q.add(p1);
		} catch (DuplicatePassengerException e) {
			e.printStackTrace();
			// if it gets here, something went wrong
			fail();
		}

		int index = q.indexOf(p1);
		assertTrue(p1.equals(q.remove(index)));

	}

}
